About Mark Nichols

I’m from Manhattan Kansas and I’ve been a nerd since before being a nerd was popular. Today I happily work at Kansas State University.

The RSS's url is : https://zanshin.net/atom.xml

Please copy to your reader or subscribe it with :

Preview of RSS feed of Mark Nichols

How to Remove Outdated Local Git Branches

2024-04-17 20:13:18

To clean up local Git branches that no longer exist on the upstream repository, you can run these commands.

Update your working copy

To start, make sure your working copy is up to date.

git fetch --prune

The --prune option removes and remote tracking references that no longer exist on the remote repository.

Discover which branches are already merged

By running

git branch

You get a list of all the branches on your working copy. Using the --merged flag, filters that list to show only those branches that are already merged into the main or master branch.

git branch --merged

Delete all merged branches

To delete all the merged branches from your working copy, run this command.

git branch --merged | egrep -v "(^\*|master|main)" | xargs git branch -d

The list of merged branches is piped to an egrep command that eliminates the master or main branch, as we don’t want to delete those. The remaining branch names are pipes to the git branch -d command, which deletes them.

Notes

Whenever I find a command or set of commands online, that purport to accomplish some task, I always break the command down, and execute each stage of it, to make sure I understand what it is doing, and to ensure that it does what the author claims. Trust, but verify.

How to See Only Active Network Interfaces on Macos

2024-03-04 23:10:45

MacOS has a number of network interfaces making the output from ifconfig messy and not easily visually parsed.

Network Interfaces

A non-exhaustive list of network interfaces you might see on MacOS includes

List current IP addresses

A simple way to see the current list of IP addresses your Mac has is by using an alias like this.

alias inet='ifconfig | grep inet | grep -v inet6'

Which produces output similar to this.

   ❯ inet inet 127.0.0.1 netmask 0xff000000
        inet 192.168.6.39 netmask 0xfffffc00 broadcast 192.168.7.255
        inet 192.168.65.1 netmask 0xffffff00 broadcast 192.168.65.255
        inet 100.101.18.109 --> 100.101.18.109 netmask 0xffffffff

While that can be useful, it would be nicer to know which interface had which IP address.

List current IP addresses and the network interface

This command will display the name of the network interface and the assigned IP address for the active network interfaces.

ip -4 addr show | awk '/inet/ {print $NF, $2}' | column -t

In order for this command to work, the iproute2mac formula via Homebrew.

The ip -4 addr show displays all the network interfaces having an IPv4 address.

❯ ip -4 addr show
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1/8 lo0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        ether 74:a6:cd:b6:eb:7f
        inet 192.168.6.39/22 brd 192.168.7.255 en0
utun8: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        inet 100.101.18.109 --> 100.101.18.109/32 utun8
bridge100: flags=8a63<UP,BROADCAST,SMART,RUNNING,ALLMULTI,SIMPLEX,MULTICAST> mtu 1500
        ether 76:a6:cd:6b:c1:64
        inet 192.168.65.1/24 brd 192.168.65.255 bridge100

The awk statement filters for the line containing inet and then prints the last field from that line ($NF) and the second field ($2). The last field is the interface name and the second field is the assigned IP address.

The column -t command formats the output into columns.

❯ inet
lo0        127.0.0.1/8
en0        192.168.6.39/22
utun8      100.101.18.109
bridge100  192.168.65.1/24

Neovim Paste and Indent

2024-02-07 08:30:52

Today I learned that you can paste and match surrounding indentation at once. After selecting the line or block of lines to be pasted, use ]p instead of only p. Et voila.

I am embarrassed to think of the hundreds, thousands of copy-paste operations I’ve done that were immediately followed by selecting the newly pasted block and fixing its indentation. I need the read the friendly manual more.

Putting a Conditional Clause in an Ssh Config

2024-02-06 12:02:22

Enough years ago that I no longer remember when I discovered this trick, I added the following clause to my .ssh/config file.

# Access GitHub even when port 22 isn't available
Host github.com
  HostName ssh.github.com
  Port 443
  user git

In a nutshell, this allows you to access GitHub over port 443, instead of the usual port 22. Various places block port 22 traffic; having this in your configuration file sidesteps that problem.

Until last week this worked perfectly. Then it stopped working, but only on my work laptop. Not on my personal laptop, not on the Linux admin workstation running in AWS, not from any of my collection of Raspberry Pies or the Intel NUC that is my IRC and mutt host, only from my work laptop.

Thanks to a GitHub repository, all my configuration files are shared between the various computers I use. The same .ssh/config worked everywhere but my work computer.

Recently my employer suffered an intrusion–we were hacked. Security has been tightened considerably. Including not allowing ssh traffic over ports that aren’t :22. As soon as I commented out the GitHub clause, all my git commands started working again.

Some searching and reading of the ssh man page and a little experimenting allowed me to create this slightly altered clause.

# Access GitHub even when port 22 isn't available
# Host github.com
Match user !<user> host "github.com"
  HostName ssh.github.com
  Port 443
  user git

The Match keyword allows you to place conditions on the directives that follow. The user and host keywords (must be lowercase) let me place a guard around the GitHub port 443 setup. If I am signed in as my work id, then the clause is skipped, meaning a normal ssh connection over port 22. For any other user the clause is used, to access GitHub. There are several other keywords that Match can operate against, allowing you to create some sophisticated conditional restrictions in your .ssh/confg file.

Do It Yourself Genius Playlist

2024-01-27 11:54:48

For a long time Apple Music (nee iTunes) offered an option called “Genius Playlist”. You selected a track from your collection, and Apple generated a playlist of 25 titles that were somehow related to the seed track. I had 15 or 20 of these. It was my own personal radio station. One without ads or an annoying DJ talking over the intro or outro of a song.

I’m not sure when Genius Playlists were eliminated from Music, but I miss that option. So I set out to make my own. Once upon a time fifteen or more years ago, I remember reading an article where someone created a set of smart playlists that categorized tracks, and then a master playlist that used those category lists as its input.

What I have create are four category smart playlists:

  1. Never Played
  2. Not Played in 90 Days
  3. Not Recently Played
  4. Recently Played.

I also scrolled through the list of tracks and ticked the “favorite” star on several hundred tracks that I particularly like.

Never Played: Tracks that are favorites, and have a play count of zero.

Not Played in 90 Days: Tracks that are favorites, and that haven’t been played in the last 90 days, but have a non-zero play count.

Not Recently Played: Tracks that are favorites, that have been played less than 90 days ago, but more than 15 days ago.

Recently Played: Tracks that are favorites, that have been played in the past 14 days.

Each of these category lists is limited to 50 tracks are are selected randomly.

The master list draws from all four category lists. Where the category lists AND all the rules together-Favorite AND never played-the master list ORs the rules-Playlist is Never Played OR Playlist is Not Played in 90 Days OR ….

The master list is also set to only 25 tracks, randomly selected.

I understand that the Never Played playlist will eventually run dry. And I’m not completely satisfied with using date ranges for the rest of the lists. What would work better, but requires considerable work, would be to rate tracks from 1 to 5 stars, and build lists around ratings and play frequency. A long term project.

Use Asdf to Manage Neovim Nightly

2024-01-08 12:43:10

I’ve been using the Neovim nightly build for some time. The way I have been accomplishing this is to update my local clone of the Neovim repository, and then make and install the application. This works, but it does take a little time.

With asdf and the neovim plugin I can easily update to the latest nightly version.

To add the neovim plugin to asdf

asdf plugin add neovim

To install the nightly build of neovim

asdf install neovim nightly

To make the nightly version the global default

asdf global neovim nightly

In order to update the nightly version you need to remove the old nightly version first, so I have this bash alias setup.

alias update-nvim='asdf uninstall neovim nightly && asdf install neovim nightly'

And, since asdf will let me have multiple version of Neovim installed, I could have the stable version on hand, and use it for a project if I wanted to.

Using asdf to Manage Software Versions on Macos

2024-01-08 03:15:18

After reading Thorsten Ball’s Register Spill newsletter about New Year, new job, new machine I decided to give asdf a try. It’s a single piece of software designed to manage multiple versions of any number of other pieces of software. Like rbenv or rvm is to Ruby, asdf is to Ruby, and Python, and NodeJS, and, and, and.

Here’s how I set it up.

Step One

Clone the GitHub repository. Installing it via Homebrew apparently has some issues. Running this command will close the 0.13.1 version into the .asdf directory in your $HOME.

 git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1

Step Two

Install some plugins to manage the software of your choice. You can get a complete list of plugins available by running:

asdf plugin-list-all

I actually piped the output through grep to make finding the software I wanted a bit quicker.

asdf plugin-list-all | grep ruby

With the plugin name and repository information, run:

asdf plugin install ruby

Step Three

Determine the version, or versions, of the software you want.

asdf list all ruby

Step Four

Install the software.

asdf install ruby latest

or

asdf install ruby 3.3.0

Step Five

Set the version globally. (It can be overridden on a project by project basis.)

asdf global ruby latest

There is no Step Six.

Using asdf means I have one set of software version management commands to remember, and one location where that information, and those versions, are kept. Better still, the version information can be shared, say with your team, ensuring everyone has the same versions of required tools installed.

Five Useful Bash Aliases

2023-12-25 21:51:36

Here are five bash aliases that I find useful.

List contents of current directory, sorted by size

alias 'dus=du -sckx * | sort -nr'

Here is a breakdown of the command.

The output of the du -sckx * command is then piped to sort -nr.

Show all currently assigned IPv4 IP addresses

alias inet='ifconfig | grep inet | grep -v inet6'

Here is a breakdown of the command.

Depending on your OS you may need to use ip a instead of ifconfig.

List directory contents sorted by modification time

alias latr='ls -latr'

Here is a breakdown of the command.

The mnemonic I use for this alias is “later”.

Look up a word’s definition

alias 'define=curl dict://dict.org/define:"$@"'

Here is a breakdown of the comment.

Make a password

alias makepass='openssl rand -base64 15'

Here is a breakdown of the command.

Setting Up Umami Site Tracking

2023-12-18 21:53:48

In December 2005 I purchased a license for Mint, a website visitor tracking tool. Written in PHP and utilizing JavaScript, it was an elegant approach to understanding what kind of traffic your website was getting. Mint hasn’t been developed in ten years, and is no longer supported. I have had to patch the source code a couple of times in recent years to keep it functioning. Mint showed you visit (by hour, day, week, month, or year), session information, referrers, pages viewed, and information about the browser/platform used by the visitor. The site layout was beautifully constructed and a joy to use. Mint also allowed for plugins, called Peppers. There was at one time a fairly active set of Peppers you could add to gain further insight into your site’s visitors.

Both my wife and I have used and continue to use Mint. Largely since the current crop of visit tracking services or products are all aimed at competing with Google Analytics. They are complex and have noisy interfaces, and generally aren’t useful for our purposes. I have been looking for a new site tracking tool for years, but haven’t found one I liked. That is until I happened on to Umami.

The interface is simple, and, as my wife put it, “highly clickable”. It doesn’t try to be the next Google Analytics, but it does provide lots of useful information for owners of small websites. Visit counts, pages viewed, visit duration, and information about their location and browsers. Even better it is respectful of data privacy, and meets EU GCPR requirements. There is a cloud service and a self-hosted option.

Signing up for the cloud service was quick an easy. Once you add a site a tracking code is generated that you add to the HTML <head> section of your page. For my site, which is statically generated using Hugo adding the tracking code was simple. Adding the code to WorkPress for my wife’s site was a bit more complicated.

Her site uses a free version of a highly customize-able theme, which makes adding code, ah, tricky. There is a plugin called “Integrate Umami” that purports to insert the tracking code into your WordPress site, but I was unable to get it to work. Instead I found another plugin called WPCode that lets you, among other things, insert code into the <head> section of your site. That solved the problem of getting the tracking code for my wife’s site in place.

We’ve only had Umami for two days now, so it is too early to tell how satisfied we’ll be in the long term, but our initial reaction is positive. For now I’m leaving our creaky Mint infrastructure in place. It’ll be interesting to compare the numbers between Mint and Umami. Umami also provides some API documentation, it might be interesting to see if I can import at least some of the history from Mint into Umami.

Replacing a Dead Iphone

2023-10-30 10:31:06

For the past 3 (4?) weeks my iPhone 14 Pro has been randomly rebooting itself. Once a day, maybe once a week. Annoying but not the end of the world. Yesterday morning the phone rebooted over and over. After each restart it work for a minute or two and then reboot again. After a quick search I learned that you can force stop an iPhone by quickly pressing and then releasing the up volume button, then the down volume button, and finally holding the power button until the Apple logo appears.

Doing that got it out of the endless reboot cycle. When I restarted it again it started and appeared to be working. I tried to make a backup to my laptop, but it rebooted in the middle of that process. More searching suggested that upgrading the operating system was something to try. The 17.1 release was out, but I hadn’t installed it yet. It took maybe 4 or 5 more reboots before I managed to get the upgrade to complete.

After the upgrade it seemed more stable. Still, I initiated a support chat with Apple. After collecting some diagnostics remotely, the support representative said that I needed to bring the phone in for repair. She said there was “stability issues”.

I did complete an iCloud backup, and for the rest of the day, my phone mostly worked. It only rebooted one more time (that I was aware of).

This morning it restarted and then it came up with the restore screen. This is an image of a laptop and a lightning cable. You need to plug the phone in. Doing that presented me with two options: restore or update. Restoring would keep the previous settings, updating wipes the phone and starts over fresh.

The restore failed twice in a row. I tried the update once, it also failed. I started another support chat, wanting to see how (or if) I could restore my phone to my iPhone 6S Plus. Between the 6S and the 14 Pro I had a 12 Pro. That phone was dropped and had a small chip in the edge of the screen. I traded it in last September for the 14 Pro, so the only device I could go back to was the 6S Plus.

As it turns out there are two reasons why that couldn’t work. One, you have to restore to the same OS version, and the 6S tops out at iOS 15. A long way away from 17.1. Second, you need at least as much storage. My 14 Pro had just over 130 GB in use. Far more that the 6S could ever hold.

I was able to make a Genius Bar appointment for the middle of the afternoon. The nearest Apple store is 125 miles away in Kansas City. After a quick shower and lunch my wife and I drove to Kansas City to the Apple Store.

The people there were very helpful, and frank. After reviewing the chat records the woman, whose name escapes me, said that the “stability” issue were an indication that the main board had failed. The only way this phone would work again would be to replace that board. It costs about $650.

The other option was to buy a new iPhone. Using the Apple Card I could make monthly payments, so $55-ish dollars a month instead of $650 all at once. In the end I decided to get the new phone.

After waiting about 20 minutes for the pick-up-in-the-store order to arrive after buying it online, I went through the setup and restore process in the store. The phone had to install the 17.1 update first, which took a good 30 minutes, the restore from iCloud started. Transferring the phone number from the old phone to the new phone was not straight-forward.

Since my old phone was inoperable, there was no way to confirm the switch using that device. So I had to sign into AT&T and initiate the transfer there. Fortunately I knew the sign in account and password. The representative at the setup table said most people didn’t know how to access their account that way. I had to have it send a code to my wife’s phone (also on the same account) and then have her forward that code to me. Having my laptop with me proved to be useful. I was able to use Messages on the Mac to chat with her.

One surprise silver lining was that my Apple Watch synced with the new iPhone. I didn’t even lose today’s activity rings. Having closed all three activity rings every day for the past 8 years, I wasn’t happy about the possibility that I’d lose my streak over a dead phone.

Once the number was activated, and the restore was progressing I was able to leave the store with a working phone. My iPhone 14 Pro case sorta fits on the 15 Pro. It fits well enough to protect it until a new case arrives on Tuesday. I also ordered a screen protector.

I did spring for Apple Care, for the first time ever. Had the 14 Pro been covered, I would have gotten a new phone at no cost to me. Even if the 14 Pro was damaged, I’d only have to pay a nomimal $29 to repair the screen, and then get a new phone. I have had iPhones since the 4 came out, and have never had one die like this. The iPhone 12 Pro was the first one that ever got damaged.

I am grateful that we were able to travel for 4+ hours today to get to an Apple Store. And that I can afford another $50 a month for a new phone—while still paying off the last 11 months of the new iPhone 14 Pro shaped paper weight I have. I am grateful that the Apple people, both on chat and in person, were friendly, helpful, and empathetic.

Apple Carplay Autoplay Automation

2023-09-17 09:58:05

While Apple CarPlay is a wonderful feature to have in our car, there is one annoying aspect that has been bothersome. When you plug your phone in and start the car, it automatically starts playing what you were last listening to—music, audiobook, or podcast. Having to wait for the sound to start so that you can push the button to turn the audio off is annoying.

Searching online I found any number of articles with a variety of solutions. Everything from removing Music from the allowed apps in CarPlay, to buying a 99¢ blank track that you name so it is the first item in your music list, and so on. The best solution, and the one I implemented, was to use a personal automation.

Search for the “Shortcuts” app on your iPhone, and select the “Automation” tab. Create a new personal automation that is triggered by “When CarPlay Connects”. For the action search for “Play/Pause”. Tap on the Play/Pause option and select “Pause”. You will have the option to be asked to allow the automation each time. I opted for no, but I did opt to get a notification when the automation ran.

After setting this up, when I plug my phone in to the car there is a split second of sound and then the sound stops. It would be better if Apple would add an autoplay on/off option, but in the meantime being able to automate silence is acceptable.

Apple Carplay for the Win

2023-09-12 09:42:41

My wife and I are on a two-week driving vacation. From our home in Manhattan Kansas we are driving to Worcester MA, with stops along the way in West Lafayette IN, State College and Scranton PA.

Our new (to us) Honda CR-V has Apple Car play, something I have wanted to have in a car since it was announced. The first two days of driving were over ground I’ve covered many times before, so I had the map displayed but didn’t really use it or need it. Leaving Tipp City (north of Dayton OH) this morning I wanted directions to get around Columbus, So I put in Wheeling WV as a destination, just to get the map pointed in the right direction.

The first thing I noticed was that, when the map is in give-you-directions mode, it shows the current posted speed limit. When you just have the map displayed but aren’t using it for navigation you don’t see that. (I guess you could tap on the map to bring up the information overlays, even without a destination.)

The second thing was that Siri would announce upcoming speed traps, apparently crowd sourced from other drivers who used the built in report feature to pass on that information.

The third thing, and by far the most impressive to us, was getting an announcement that I-70 East was closed ahead of us, with an estimated delay of 45 minutes (This estimate was at least an hour before we arrived at the start of the alternate route, by then the delay had grown considerably). We took the suggested alternate route, which put us on a 4-lane state road parallel to the Interstate. Several other cars took the same route, and several semis did as well. Most of the traffic continued on past the alternate route exit. From that exit you couldn’t see any sign of a road closure. My guess is the other cars were also using CarPlay and decided to follow the suggested alternate route. Not all the semis took the alternate, so maybe some trucks have CarPlay and some don’t? Is CB still a thing in the age of cell phones?

Part way along the detour, we could see the Interstate, and the east bound lanes were a massive parking lot. Miles of cars and trucks standing on the highway. Having CarPlay saved us hours of time and frustration today. This evening I did a Google search and learned that a semi and crashed against a barrier, caught fire, and dumped its load on the highway. It took several hours to clean up and reopen the highway.

This one event makes CarPlay worth it. I don’t ever want to travel long distance by car again without it.

Not So Special Apple Special Offer

2023-07-01 23:48:32

Ever since the 13-inch M2 MacBook Air was released, I’ve wanted a new laptop. When the 24-inch iMac was released both my with and I bought one for ourselves. The iMac is a stunningly beautiful machine, thin, elegant, colorful. A home run. Except that it is a desktop, and I do a majority of my personal computer from the living room couch, or dining room table, or on the treadmill desk. In order to use the iMac I had to go into my home office (a pleasant, comfortable space) and be apart from the rest of the house.

The new MacBook Air looked like the perfect replacement for the iMac. Then rumors of a new 15-inch MacBook Air started to circulate. I decided to wait until WWDC to see what Apple might announce then. As anticipated they announced a new M2 powered 15-inch MacBook Air. I was sold.

Working at a university allows me to take advantage of the educational discount. Trading in my 24-inch iMac knocked another $490 from the price. When I went to review the bag, there was a “special offer.” A $150 Apple Gift card. This lowered the monthly installment for the laptop from $135.75 to $123.25 - a $12.50 savings per month. I pressed the buy button and started counting the days until delivery.

I’ve had my new MacBook Air for a couple of weeks now. It is everything I hoped it would be. I am extremely pleased with it.

Today is July 1st, so any Apple purchases using my Apple Card, and the free installment plans Apple offers are due on the 1st each month. Opening my wallet I saw the installment for my iPhone, the new installment for my MacBook Air, and a $12.50 installment, 1 of 12, for the Apple Gift Card.

While Apple lowered the cost of the laptop $150, they didn’t lower my monthly installment cost at all. In my excitement to order the new laptop I didn’t pay close enough attention to the invoice. I verified that the laptop specification were what I wanted, and accepted that Apple was knocking another $150 from the price.

I would rather they had given me a pair of AirPods–at least those I could sell. After calling Apple Support, I learned there really wasn’t anything that could be done. Between the time I got the gift card email, and today, I renewed an app subscription and that cost was deducted from the gift card. Had that even not occurred they would have credited the $150 toward the laptop, actually bringing my monthly installment cost down to $123.25. Since there was already activity, even inadvertent activity, on the gift card, they were unable to do anything except listen to my complaint. To the representative’s credit, she did hear my complaint, acknowledged that I wasn’t the only person who was unhappy about this outcome, and agreed to pass it up the line.

I opened up the Apple store and recreated my order. When I got to the “review your bag” step of the process, I looked more carefully at everything there. The special offer did show that it would be a $12.50 installment for 12 months. Apple didn’t bait-and-switch me, but they also didn’t call out that you were not saving any money, you were just getting the chance to spend some of the money on other purchases.

I’ve been buying Apple products for over twenty years. I still have my PowerBook G4, and a 17-inch iMac G4. I am an Apple fan. I wish the checkout process had thrown up a separate page that detailed the special offer and its terms. Having it on the same page as the shiny new laptop is a bit of a dark pattern. I still would have purchased the laptop, but I would have avoided the surprise today of seeing two new installment payments, rather than the one new one I expected.

Adventures in Technical Debt

2023-04-20 07:22:58

Almost five years ago the University where I work suffered a fire in the main library building on campus. This building also houses, in the basement, the (then) primary data center. Two holes in the ceiling of the data center, which had been made to allow conduit runs, had not been properly sealed. We had a major water intrusion.

In the months that followed, as we worked to restore services and find ways to move out of the now compromised data center, we used VMware Cloud on AWS. Most of our production servers were virtual machines running in vSphere in our vBlock. With VMC we could “lift and shift” workloads from on-premises to AWS relatively quickly.

This spring we are working to upgrade all our Ubuntu servers to version 22.04. This required some adjustments to our mod_cluster configuration and our Apache configuration. Fortunately we have a test environment and an infrastructure automation tool to help make test and prod the same.

Our infrastructure automation tool is Chef. One of the features of Chef is the ability to “pin” the version of resources through the environment. All the nodes (Chef parlance for server) exist within an environment, with clever names like “test”, or “prod”. When we set out to migrate to VMC a new environment was created, called “prodvmc”. Catchy.

At about the same time, some version pinning occurred in the “prod” environment. Pinning that was never revisited. Pinning that was committed to the repository with no meaningful comments as to why the versions were pinned.

All of our Ubuntu 22 testing occurred, naturally enough, in the “test” environment. We never exercised the pinned versions. Also, apparently to reduce setup time in Vagrant, some resource definitions had code that said, “don’t do this if the environment is ’test’”.

Both of these decisions have produced some technical debt we now have to pay. The infrastructure automation code that is stepped around for the test environment hasn’t proved to be hard to overcome. Frustrating perhaps, but not insurmountable.

Unwinding the version pinning is a much larger debt. Our applications are Java-based web applications running in Wildfly application server. One of the resources that was pinned is the primary definition for our Wildfly clusters. A definition used by all of our major applications.

Not all of the servers belong to the “prod” environment. Slightly more than half belong to the “prodvmc” environment, where there was no pinning. For the rest, we now need to revisit four years of commits to determine what will happen to these production resources, when we remove the pinning constraint and update to the latest version of the infrastructure definition.

One measurement of an organization’s maturity, is how well things are documented. In our haste to move to VMC we made a decision to pin some versions, most likely thinking, “This is temporary for reason “x”, we’ll come back and address this once the move is completed.” And then we never went back. Not going back apparently hasn’t had too large an impact since all our applications are working. But not documenting the reason for the decision is going to cost us some time.

Lessons to learn:

Mob Programming

2023-04-15 09:47:01

I spent the better part of two work days this week mob programming. Solo programming is easy, you and a computer, and your favorite text editor. Pair programming (which I have never done) sounds like it would be interesting. Two minds, two differing approaches, one problem. Done right, it could be very empowering. Mob programming is what happens when there are three, four, and even five people on the Zoom call, watching one person “drive” and offering ideas, suggestions, and feedback.

I found it exhausting. It was very easy to lose track of the current thread, of the current approach to solving the problem. Depending on who was driving at the time it was very difficult to keep up with what they were doing. (Imagine an editor with 5 open tabs, each titled “UNNAMED” that the person is jumping back and forth between.)

We ultimately resolved the issue, but not efficiently, and not in a reproducible way. Maybe not reproducing it is actually a plus. I think with two, or maybe three people, you can focus on a problem and make steady progress. If one member of the group gets too close to the tree, at least one other person and pull them back to see the forest. Somehow with four people, and also with five, you end up with scattered approach. Two or three forests aren’t being seen for two or three trees.

If I find myself headed into a similar situation-two of us working and deciding to bring in another for assistance-I think the designated driver needs to be very up-front about directing what is going on. I also think it would help if the driver narrated what they were doing, even to the point of saying things like, “I’m going to open a new tab to pull up this code …”.

No more mob programming for me.

How to Split a Subfolder Into a New Repository

2023-04-14 23:48:33

Recently at work I had to split a sub-folder in a repository into its own repository. I wanted to keep the commit history. My search online led me to Splitting a subfolder out into a new repository on the GitHub Dos site.

The instructions there are very good. In a nutshell what I did was this.

In all the process took about 5 minutes. Not something I’ll do every day, but it is nice to know it is possible.

Can Water Solve a Maze

2023-04-14 09:33:30

Software Defined Behavior

2023-04-14 08:28:30

For the past ten years or so, my primary terminal emulator has been iTerm2. Recently I have been experimenting with other terminal emulators. The current test subject is Alacritty. Switching to a different piece of software has exposed a learned behavior that I’m not sure I’m willing to give up.

iTerm2 employs what I think of as a document model. You open the software once, but can have multiple “documents” open simultaneously. In this case each document is another terminal session. Since they are all children of the application you can cycle through them using the CMD-` keyboard shortcut.

On the desktop where I keep my terminal windows (multiple desktops is another topic for another day), I typically have three terminal windows open. In the upper left quadrant I have a window where I keep my daily log open in a text editor. The lower left quadrant has a window where my ICR client (Weechat) and Mutt email live, each in their own tmux window. Both Mutt and Weechat run on a small server in my home, so I ssh into that machine and attach to a tmux session which holds those two applications. The right side of my screen is a single terminal window where I do most of my work. I usually have several tmux session defined, each centered around either a long running task, or some recurring administration function I want to return to again and again.

Since iTerm2 uses a document model I can use the CMD-` shortcut to hop from terminal to terminal. Alacritty does not employ a document model. Each of the three terminal windows described above is a unique instance of Alacritty. In order to switch from one to another I need to use CMD-Tab. CMD-Tab brings up the application switcher, and sometimes there are several applications I have to tab past to get to the next Alacritty window. Furthermore, from the application switcher you can’t tell which Alacritty window you are about to open. When you CMD-` you are taken to the window so you know immediately which window you are at.

For now, I’m going to return to iTerm2 so I can keep my in-application window switching ability.

Checklists and Procedures

2023-03-08 22:52:51

As a programmer / site reliability engineer / cloud infrastructure administrator I am very familiar with processes and procedures. Some are anecdotal and others are formalized. The best ones are automated, so that they are precisely repeatable.

My wife is having hip replacement surgery today. As with her first hip replacement last year, there are a number of processes and procedures at play, and a few checklists. We both appreciate the thoroughness of the preparation. Having each stage mapped out, knowing what to expect, and having people verify and explain as they go, all make the experience better.

One of the procedures requires no food or drink within six hours of the surgery. Usually they tell you nothing after midnight, regardless of the procedure time, as it is a definite, unambiguous time.

As a part of the pre-op preparation, there were several pills my wife needed to take. She is unable to swallow pills using water alone. We explained this prior to the first surgery to the hospital intake nurse, to the anesthesiologist who called the day before, and to the nurses preparing her for surgery. In order to swallow pills my wife use a small bite of soft food: a cracker chewed up, or a bite of banana.

On the morning of the first surgery the nurse presented her with a little cup full of pills and a small cup of water. We explained once again the inabilty to swallow with only water. So the pills didn’t happen.

We explained this requirement again during all of the pre-op visits and calls. During the pre-op anesthesiologist phone call yesterday, we again explained about the need for a small bite of soften food to swallow pills. This morning we explained that to the nurse. She offered a saltine cracker, which did all the pills to be taken. An hour later, as we were waiting in the holding bay outside the operating room, we were told that due to the cracker surgery would have to be delayed. By six hours.

The procedure wasn’t followed. Had the nurse contacted the anesthesiologist for today’s surgery and asked, it might have been allowed, or they may have said, “Nope, no food”. Either way the surgery would have happened at the original 9 am time. Since there wasn’t any communication to verify the use of a cracker, the surgery was delayed.

I understand and appreciate the importance of procedures and checklists, and that there are consequences for not following them. That the surgeon and anesthesiologist are paying that much attention bolsters my confidence in their focus and dedication to my wife’s care.

The consequence of not following the no food edict is a six hour delay. The irony is that the efficacy of the medication taken at 7 am with a bite of cracker will have worn off by the start time of the delayed surgery.

Infinited Lego Domino Ring

2023-02-20 21:49:38

Whenever my wife or I sees something like this, we’ll say, “When do people think up stuff like this?”, to which the other will say, “Not between 9 and 5.”